﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;

using SBPweb.RIA.Client.Controls.Base;
using SBPweb.RIA.Client.Controls.Content;
using SBPweb.RIA.Client.Controls.Extensions;

namespace SBPweb.RIA.Client.Controls.Windows
{

    [TemplatePart(Name = "Root", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "bChrome", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "grdChrome", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "cpContent", Type = typeof(FrameworkElement))]
    //[TemplatePart(Name = "Overlay", Type = typeof(Panel))]
    //[TemplatePart(Name = "Resizer", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "btnClose", Type = typeof(ButtonBase))]
    [TemplateVisualState(Name = "Open", GroupName = "WindowStates")]
    [TemplateVisualState(Name = "Closed", GroupName = "WindowStates")]
    public partial class Window : ContentControlBase
    {

        #region Constants

        public const string HorizontalOffsetPropertyName = "HorizontalOffset";
        public const string VerticalOffsetPropertyName = "VerticalOffset";

        public const string WidthPropertyName = "Width";
        public const string HeightPropertyName = "Height";

        public const string IsOpenPropertyName = "IsOpen";

        #endregion

        #region Fields

        private bool shouldOpen;
        private bool isMoving;
        private bool isResizing;
        private bool isInitialized;
        private bool isLoaded;
        private bool? dialogResult;
        private Point pointOfDragging;
        //private Popup modalPopup;
        //private Grid modalPopupGrid;
        private Grid grdBackground;
        private Border bChrome;
        private Grid grdChrome;
        private Button btnClose;
        private Image imgIcon;
        private Grid grdResizer;
        private ScaleTransform tranScale;
        private FrameworkElement templateRootElement;

        private static int z;

        #endregion

        #region Constructor logic

        public Window()
            : this(default(Canvas))
        {
        }

        public Window(string rootElementName)
            : this(ExtendableApplication.Current == null || ExtendableApplication.Current.IsDesignTime ? null :
                    ExtendableApplication.Current.RootVisual.FindChildElement<Canvas>(ExtendableApplication.Current.RootVisual, rootElementName))
        {
        }

        public Window(Canvas rootElement)
            : base()
        {
            ParentLayoutRoot = rootElement;
            InitializeDefaultValues();
        }

        #endregion

        #region Dependencies

        public static readonly DependencyProperty HasCloseButtonProperty = DependencyProperty.Register("HasCloseButton", typeof(Boolean), typeof(Window), null);
        public static readonly DependencyProperty OverlayColorProperty = DependencyProperty.Register("OverlayColor", typeof(Color), typeof(Window), null);
        public static readonly DependencyProperty ChromeBrushProperty = DependencyProperty.Register("ChromeBrush", typeof(Brush), typeof(Window), null);
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(Window), null);
        public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(object), typeof(Window), null);
        public static readonly DependencyProperty IconSourceProperty = DependencyProperty.Register("IconSource", typeof(ImageSource), typeof(Window), null);
        public static readonly DependencyProperty IconWidthProperty = DependencyProperty.Register("IconWidth", typeof(double), typeof(Window), null);
        public static readonly DependencyProperty IconHeightProperty = DependencyProperty.Register("IconHeight", typeof(double), typeof(Window), null);
        public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.Register(HorizontalOffsetPropertyName, typeof(double), typeof(Window), null);
        public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register(VerticalOffsetPropertyName, typeof(double), typeof(Window), null);

        #endregion

        #region Properties

        public bool? IsOpen
        {
            get;
            private set;
        }

        public bool? IsClosed
        {
            get;
            private set;
        }

        [TypeConverter(typeof(NullableBoolConverter))]
        public bool? DialogResult
        {
            get
            {
                return dialogResult;
            }
            set
            {
                dialogResult = value;
                Close();
            }
        }

        public bool HasCloseButton
        {
            get
            {
                return GetValue<bool>(HasCloseButtonProperty);
            }
            set
            {
                SetValue<bool>(HasCloseButtonProperty, value, "HasCloseButton");
            }
        }

        public bool IsModal
        {
            get;
            protected set;
        }

        public bool IsPersistable
        {
            get;
            set;
        }

        public Color OverlayColor
        {
            get
            {
                return GetValue<Color>(OverlayColorProperty);
            }
            set
            {
                SetValue<Color>(OverlayColorProperty, value, "OverlayColor");
            }
        }

        public Brush ChromeBrush
        {
            get
            {
                return GetValue<Brush>(ChromeBrushProperty);
            }
            set
            {
                SetValue<Brush>(ChromeBrushProperty, value, "ChromeBrush");
            }
        }

        public Canvas ParentLayoutRoot
        {
            get;
            set;
        }

        public ResizeMode ResizeMode
        {
            get;
            set;
        }

        public string Title
        {
            get
            {
                return GetValue<string>(TitleProperty);
            }
            set
            {
                SetValue<string>(TitleProperty, value, "Title");
            }
        }

        public object Icon
        {
            get
            {
                return GetValue<object>(IconProperty);
            }
            set
            {
                SetValue<object>(IconProperty, value, "Icon");
            }
        }

        public ImageSource IconSource
        {
            get
            {
                return GetValue<ImageSource>(IconSourceProperty);
            }
            set
            {
                SetValue<ImageSource>(IconSourceProperty, value, "IconSource");
            }
        }

        public double IconWidth
        {
            get
            {
                return GetValue<double>(IconWidthProperty);
            }
            set
            {
                SetValue<double>(IconWidthProperty, value, "IconWidth");
            }
        }

        public double IconHeight
        {
            get
            {
                return GetValue<double>(IconHeightProperty);
            }
            set
            {
                SetValue<double>(IconHeightProperty, value, "IconHeight");
            }
        }

        [Category("Layout")]
        public double HorizontalOffset
        {
            get
            {
                return GetValue<double>(HorizontalOffsetProperty);
            }
            set
            {
                SetValue<double>(HorizontalOffsetProperty, value, HorizontalOffsetPropertyName);
                //if (isInitialized && isLoaded && !isMoving && Application.IsSettingsPersistencyEnabled)
                //{
                //    this.StorePersistedProperty<double?>(HorizontalOffsetPropertyName, value);
                //}
            }
        }

        [Category("Layout")]
        public double VerticalOffset
        {
            get
            {
                return GetValue<double>(VerticalOffsetProperty);
            }
            set
            {
                SetValue<double>(VerticalOffsetProperty, value, VerticalOffsetPropertyName);
                //if (isInitialized && isLoaded && !isMoving && Application.IsSettingsPersistencyEnabled)
                //{
                //    this.StorePersistedProperty<double?>(VerticalOffsetPropertyName, value);
                //}
            }
        }

        [Category("Layout")]
        public new double Width
        {
            get
            {
                return GetValue<double>(WidthProperty);
            }
            set
            {
                SetValue<double>(WidthProperty, value, WidthPropertyName);
                //if (isInitialized && isLoaded && !isResizing && Application.IsSettingsPersistencyEnabled)
                //{
                //    this.StorePersistedProperty<double?>(WidthPropertyName, value);
                //}
            }
        }

        [Category("Layout")]
        public new double Height
        {
            get
            {
                return GetValue<double>(HeightProperty);
            }
            set
            {
                SetValue<double>(HeightProperty, value, HeightPropertyName);
                //if (isInitialized && isLoaded && !isResizing && Application.IsSettingsPersistencyEnabled)
                //{
                //    this.StorePersistedProperty<double?>(HeightPropertyName, value);
                //}
            }
        }

        [Category("Layout")]
        public ModalPositionings ModalPositioning
        {
            get;
            set;
        }

        internal FrameworkElement ContentRoot
        {
            get
            {
                return templateRootElement;
            }
        }

        #endregion

        #region Events

        public event EventHandler<CancelEventArgs> Opening;

        public event EventHandler Opened;

        public event EventHandler<CancelEventArgs> Closing;

        public event EventHandler Closed;

        public event EventHandler<CancelEventArgs> Moving;

        public event EventHandler Moved;

        public event EventHandler<CancelEventArgs> Resizing;

        public event EventHandler Resized;

        #endregion

        #region Methods

        public void Open()
        {
            BeginOpeningWindow();
        }

        public void Open(double horizontalOffset, double verticalOffset)
        {
            BeginOpeningWindow(horizontalOffset, verticalOffset);
        }

        public void OpenDialog()
        {
            BeginOpeningWindow(true);
        }

        public void OpenDialog(double horizontalOffset, double verticalOffset)
        {
            BeginOpeningWindow(horizontalOffset, verticalOffset, true);
        }

        public void Close()
        {
            BeginClosingWindow();
        }


        protected override void InitializeHandlers()
        {
            base.InitializeHandlers();
        }

        protected override void FinalizeHandlers()
        {
            if (bChrome != null)
            {
                bChrome.MouseLeftButtonDown -= new MouseButtonEventHandler(Chrome_MouseLeftButtonDown);
                bChrome.MouseLeftButtonUp -= new MouseButtonEventHandler(Chrome_MouseLeftButtonUp);
                bChrome.MouseMove -= new MouseEventHandler(Chrome_MouseMove);
            }
            if (btnClose != null)
            {
                btnClose.Click -= new RoutedEventHandler(btnClose_Click);
            }

            base.FinalizeHandlers();
        }


        protected override void OnLoaded(object sender, RoutedEventArgs e)
        {
            base.OnLoaded(sender, e);

            InitializeWidthPersistedValues();

            isLoaded = true;
        }

        protected override void OnUnloaded(object sender, RoutedEventArgs e)
        {
            isLoaded = false;
            base.OnUnloaded(sender, e);
        }


        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            if (Title == null)
            {
                Title = Name;
            }
            
            templateRootElement = this.GetTemplateChild("Root") as FrameworkElement;

            grdBackground = this.GetTemplateChild("grdBackground") as Grid;
            bChrome = this.GetTemplateChild("bChrome") as Border;
            grdChrome = this.GetTemplateChild("grdChrome") as Grid;
            btnClose = this.GetTemplateChild("btnClose") as Button;
            imgIcon = this.GetTemplateChild("imgIcon") as Image;
            grdResizer = this.GetTemplateChild("grdResizer") as Grid;
            tranScale = this.GetTemplateChild("tranScale") as ScaleTransform;

            if (bChrome != null)
            {
                bChrome.MouseLeftButtonDown += new MouseButtonEventHandler(Chrome_MouseLeftButtonDown);
                bChrome.MouseLeftButtonUp += new MouseButtonEventHandler(Chrome_MouseLeftButtonUp);
                bChrome.MouseMove += new MouseEventHandler(Chrome_MouseMove);
            }

            if (btnClose != null)
            {
                btnClose.Click += new RoutedEventHandler(btnClose_Click);
            }

            if (imgIcon != null)
            {
                imgIcon.Visibility = IconSource != null ? Visibility.Visible : Visibility.Collapsed;
            }

            if (grdResizer != null)
            {
                switch (ResizeMode)
                {
                    default:
                        grdResizer.Visibility = Visibility.Collapsed;
                        break;
                    case ResizeMode.CanResizeWithGrip:
                        grdResizer.Visibility = Visibility.Visible;
                        break;
                }
            }

            EnsureScalingAnimation();

            if (templateRootElement != null)
            {
                var query = from state in
                                (from stateGroup in VisualStateManager.GetVisualStateGroups(templateRootElement).Cast<VisualStateGroup>()
                                 where stateGroup.Name == "WindowStates"
                                 select stateGroup).FirstOrDefault().States.Cast<VisualState>()
                            select state;
                foreach (Storyboard sb in query.Select(x => x.Storyboard))
                {
                    try
                    {
                        switch (sb.GetValue(FrameworkElement.NameProperty).ToString())
                        {
                            default:
                                break;
                            case "sbOpen":
                                sb.Completed += new EventHandler(opened);
                                break;
                            case "sbClose":
                                sb.Completed += new EventHandler(closed);
                                break;
                        }
                    }
                    catch
                    {
                    }
                }
            }

            if (shouldOpen)
            {
                if (IsModal)
                {
                    grdBackground.Margin = new Thickness(Margin.Left * -1.0, Margin.Top * -1.0, Margin.Right * -1.0, Margin.Bottom * -1.0);
                    double aW = Application.Host.Content.ActualWidth;
                    double aH = Application.Host.Content.ActualHeight;
                    templateRootElement.Width = aW;
                    templateRootElement.Height = aH;
                    bChrome.HorizontalAlignment = HorizontalAlignment.Center;
                    bChrome.VerticalAlignment = VerticalAlignment.Center;
                    Storyboard sb = this.GetStory(templateRootElement, "sbModalOpen");
                    Storyboard.SetTarget(sb, grdBackground);
                    sb.Begin();
                }

                VisualStateManager.GoToState(this, "Open", true);
                shouldOpen = false;

                bringToFront();
            }
        }


        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }


        private void Chrome_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            UIElement uie = sender as UIElement;
            FrameworkElement fwe = e.OriginalSource as FrameworkElement;
            if (fwe.HasParent<ContentPresenter>("cpContent"))
            {
                e.Handled = false;
                bringToFront();
                return;
            }
            pointOfDragging = e.GetPosition(uie);
            CancelEventArgs cea = new CancelEventArgs();
            if (Cursor == null || Cursor == Cursors.Arrow)
            {
                moving(sender, cea);
            }
            else if (ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip)
            {
                resizing(sender, cea);
            }
            if (!cea.Cancel)
            {
                uie.CaptureMouse();
            }
        }


        private void Chrome_MouseMove(object sender, MouseEventArgs e)
        {
            Point p = e.GetPosition(this);
            
            if (this.ContentRoot != null)
            {
                if (ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip)
                {
                    if ((this.ActualWidth - p.X < 10.0) && (this.ActualHeight - p.Y) < 10.0)
                    {
                        Cursor = Cursors.SizeNWSE;
                    }
                    else
                    {
                        Cursor = Cursors.Arrow;
                    }
                }

                // If the child window is dragged out of the page, return
                if (Application != null && Application.RootVisual != null)
                {
                    if (e.GetPosition(Application.RootVisual).X <= 0 || e.GetPosition(Application.RootVisual).Y <= 0)
                    {
                        return;
                    }
                }

                if (isMoving)
                {
                    if (!IsModal)
                    {
                        HorizontalOffset += p.X - pointOfDragging.X;
                        VerticalOffset += p.Y - pointOfDragging.Y;
                    }
                    else
                    {
                        TransformGroup transformGroup = bChrome.RenderTransform as TransformGroup;

                        if (transformGroup == null)
                        {
                            transformGroup = new TransformGroup();
                            transformGroup.Children.Add(bChrome.RenderTransform);
                        }

                        TranslateTransform t = new TranslateTransform();
                        t.X = e.GetPosition(bChrome).X - pointOfDragging.X;
                        t.Y = e.GetPosition(bChrome).Y - pointOfDragging.Y;
                        if (transformGroup != null)
                        {
                            transformGroup.Children.Add(t);
                            bChrome.RenderTransform = transformGroup;
                        }
                    }
                }
                else if (isResizing)
                {

                    if (p.X > (MinWidth + this.IconWidth + 24))
                    {
                        Width = p.X;
                    }
                    if (p.Y > (MinHeight + this.IconHeight + 24))
                    {
                        Height = p.Y;
                    }
                }
            }
        }


        private void Chrome_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            UIElement uie = sender as UIElement;
            if (isMoving)
            {
                moved(sender, e);
            }
            if (isResizing)
            {
                resized(sender, e);
            }
            uie.ReleaseMouseCapture();
        }


        protected virtual void OnOpening(CancelEventArgs e)
        {
        }

        protected virtual void OnOpened(EventArgs e)
        {
        }

        protected virtual void OnClosing(CancelEventArgs e)
        {
        }

        protected virtual void OnClosed(EventArgs e)
        {
        }

        protected virtual void OnMoving(CancelEventArgs e)
        {
        }

        protected virtual void OnMoved(EventArgs e)
        {
        }

        protected virtual void OnResizing(CancelEventArgs e)
        {
        }

        protected virtual void OnResized(EventArgs e)
        {
        }


        private void opening(object sender, CancelEventArgs e)
        {
            IsOpen = null;
            if (Opening != null)
            {
                Opening(this, e);
            }
            OnOpening(e);
        }

        private void opened(object sender, EventArgs e)
        {
            IsOpen = true;
            IsClosed = false;
            if (Opened != null)
            {
                Opened(this, e);
            }
            OnOpened(e);
            if (Application.IsSettingsPersistencyEnabled)
            {
                this.StorePersistedProperty<bool?>(IsOpenPropertyName, IsOpen);
            }
        }

        private void closing(object sender, CancelEventArgs e)
        {
            IsClosed = null;
            if (Closing != null)
            {
                Closing(this, e);
            }
            OnClosing(e);
        }

        private void closed(object sender, EventArgs e)
        {
            IsClosed = true;
            IsOpen = false;
            if (Closed != null)
            {
                Closed(this, e);
            }
            OnClosed(e);
            if (grdBackground != null)
            {
                grdBackground.Visibility = Visibility.Collapsed;
            }
            if (Application.IsSettingsPersistencyEnabled)
            {
                this.StorePersistedProperty<bool?>(IsOpenPropertyName, IsOpen);
            }
        }

        private void moving(object sender, CancelEventArgs e)
        {
            UIElement uie = sender as UIElement;
            if (Moving != null)
            {
                Moving(this, e);
            }
            OnMoving(e);
            if (!e.Cancel)
            {
                bringToFront();
                isMoving = true;
                isResizing = false;
            }
        }

        private void moved(object sender, EventArgs e)
        {
            if (Moved != null)
            {
                Moved(this, e);
            }
            if (Application.IsSettingsPersistencyEnabled)
            {
                this.StorePersistedProperty<double?>(HorizontalOffsetPropertyName, HorizontalOffset);
                this.StorePersistedProperty<double?>(VerticalOffsetPropertyName, VerticalOffset);
            }
            OnMoved(e);
            isMoving = false;
        }

        private void resizing(object sender, CancelEventArgs e)
        {
            UIElement uie = sender as UIElement;
            if (Resizing != null)
            {
                Resizing(this, e);
            }
            OnResizing(e);
            if (!e.Cancel)
            {
                bringToFront();
                isResizing = true;
                isMoving = false;
            }
        }

        private void resized(object sender, EventArgs e)
        {
            if (Resized != null)
            {
                Resized(this, e);
            }
            if (Application.IsSettingsPersistencyEnabled)
            {
                this.StorePersistedProperty<double?>(WidthPropertyName, Width);
                this.StorePersistedProperty<double?>(HeightPropertyName, Height);
            }
            OnResized(e);
            isResizing = false;
        }


        private void bringToFront()
        {
            this.SetValue(Canvas.ZIndexProperty, z++);
        }

        private void sendToBack()
        {
            this.SetValue(Canvas.ZIndexProperty, 0);
        }


        private void BeginOpeningWindow()
        {
            BeginOpeningWindow(null, null, IsModal);
        }

        private void BeginOpeningWindow(bool isModal)
        {
            BeginOpeningWindow(null, null, isModal);
        }

        private void BeginOpeningWindow(double? x, double? y)
        {
            BeginOpeningWindow(x, y, IsModal);
        }

        private void BeginOpeningWindow(double? x, double? y, bool isModal)
        {
            if (IsModal != IsModal)
            {
                IsModal = isModal;
            }
            if (IsOpen.HasValue && IsOpen.Value)
            {
                bringToFront();
                return;
            }
            CancelEventArgs cea = new CancelEventArgs();
            opening(this, cea);
            if (cea.Cancel)
            {
                return;
            }

            if (IsModal)
            {
                if (grdBackground != null)
                {
                    grdBackground.Visibility = Visibility.Visible;
                }
                //if (modalPopup == null && modalPopupGrid == null)
                //{
                //    modalPopupGrid = new Grid();
                //    modalPopupGrid.CacheMode = new BitmapCache() { RenderAtScale = 1.0 };
                //    modalPopupGrid.Background = new SolidColorBrush(Color.FromArgb(204, 0, 0, 0));
                //    modalPopupGrid.Name = "grdPopupRoot";
                //    modalPopupGrid.Children.Add(this);
                //    modalPopupGrid.Width = Application.Host.Content.ActualWidth;
                //    modalPopupGrid.Height = Application.Host.Content.ActualHeight;
                //    modalPopup = new Popup();
                //    modalPopup.CacheMode = new BitmapCache() { RenderAtScale = 1.0 };
                //    modalPopup.Child = modalPopupGrid;
                //    if (ParentLayoutRoot != null)
                //    {
                //        ParentLayoutRoot.Children.Add(modalPopup);
                //    }
                //}
                //switch (ModalPositioning)
                //{
                //    case ModalPositionings.Centered:
                //    default:
                //        break;
                //    case ModalPositionings.Offset:
                //        modalPopup.HorizontalOffset = HorizontalOffset;
                //        modalPopup.VerticalOffset = VerticalOffset;
                //        break;
                //}
                //modalPopup.IsOpen = true;
            }
            //else
            //{
                if (ParentLayoutRoot == null)
                {
                    throw new NullReferenceException("ParentLayoutRoot is not set!");
                }
                if (!ParentLayoutRoot.Children.Contains(this))
                {
                    ParentLayoutRoot.Children.Add(this);
                }

                if (x.HasValue)
                {
                    this.SetValue(Canvas.LeftProperty, x.Value);
                }
                if (y.HasValue)
                {
                    this.SetValue(Canvas.TopProperty, y.Value);
                }
            //}

            EnsureScalingAnimation();

            if (templateRootElement != null)
            {
                VisualStateManager.GoToState(this, "Open", true);
            }
            else
            {
                shouldOpen = true;
            }
        }

        private void BeginClosingWindow()
        {
            CancelEventArgs cea = new CancelEventArgs();
            closing(this, cea);
            if (cea.Cancel)
            {
                return;
            }

            EnsureScalingAnimation();

            if (templateRootElement != null)
            {
                if (IsModal)
                {
                    Storyboard sb = this.GetStory(templateRootElement, "sbModalClose");
                    if (sb.GetCurrentState() != ClockState.Stopped)
                    {
                        sb.Stop();
                    }
                    Storyboard.SetTarget(sb, grdBackground);
                    sb.Begin();
                }
                VisualStateManager.GoToState(this, "Closed", true);
            }
        }

        private void EnsureScalingAnimation()
        {
            if (tranScale != null)
            {
                tranScale.ScaleX = IsOpen.HasValue && IsOpen.Value ? 1.0 : 0.0;
                tranScale.ScaleY = IsOpen.HasValue && IsOpen.Value ? 1.0 : 0.0;

                if (ActualWidth != 0.0)
                {
                    tranScale.CenterX = ActualWidth / 2.0;
                }
                else if (!Width.Equals(Double.NaN))
                {
                    tranScale.CenterX = Width / 2.0;
                }
                else if (!MinWidth.Equals(Double.NaN) && MinWidth != 0.0)
                {
                    tranScale.CenterX = MinWidth / 2.0;
                }
                else
                {
                    tranScale.CenterX = Application.Host.Content.ActualWidth / 2.0;
                }

                if (ActualHeight != 0.0)
                {
                    tranScale.CenterY = ActualHeight / 2.0;
                }
                else if (!Height.Equals(Double.NaN))
                {
                    tranScale.CenterY = Height / 2.0;
                }
                else if (!MinHeight.Equals(Double.NaN) && MinHeight != 0.0)
                {
                    tranScale.CenterY = MinHeight / 2.0;
                }
                else
                {
                    tranScale.CenterY = Application.Host.Content.ActualHeight / 2.0;
                }
            }
        }

        protected virtual void InitializeDefaultValues()
        {
            DefaultStyleKey = typeof(Window);

            CacheMode = new BitmapCache() { RenderAtScale = 1.0 };

            IsClosed = true;
            IsOpen = false;

            IsPersistable = true;

            ResizeMode = ResizeMode.CanResizeWithGrip;

            FontFamily = new FontFamily("Lucida Sans Unicode");

            IconWidth = 16;
            IconHeight = 16;

            Binding bHO = new Binding();
            bHO.Source = this;
            bHO.Path = new PropertyPath(HorizontalOffsetPropertyName);
            bHO.Mode = BindingMode.TwoWay;
            SetBinding(Canvas.LeftProperty, bHO);

            Binding bVO = new Binding();
            bVO.Source = this;
            bVO.Path = new PropertyPath(VerticalOffsetPropertyName);
            bVO.Mode = BindingMode.TwoWay;
            SetBinding(Canvas.TopProperty, bVO);
            
            isInitialized = true;
        }

        private void InitializeWidthPersistedValues()
        {
            if (!IsPersistable)
            {
                return;
            }
            double? hO = this.RetreivePersistedProperty<double?>(HorizontalOffsetPropertyName);
            double? vO = this.RetreivePersistedProperty<double?>(VerticalOffsetPropertyName);
            double? w = this.RetreivePersistedProperty<double?>(WidthPropertyName);
            double? h = this.RetreivePersistedProperty<double?>(HeightPropertyName);
            bool? iV = this.RetreivePersistedProperty<bool?>(IsOpenPropertyName);
            if (hO.HasValue)
            {
                HorizontalOffset = hO.Value;
            }
            if (vO.HasValue)
            {
                VerticalOffset = vO.Value;
            }
            if (w.HasValue)
            {
                Width = w.Value;
            }
            if (h.HasValue)
            {
                Height = h.Value;
            }
            if (iV.HasValue)
            {
                shouldOpen = iV.Value;
            }
        }

        #endregion

    }

    public enum ModalPositionings
    {
        Centered,
        Offset
    }

    public enum ResizeMode
    {
        NoResize = 0,
        CanMinimize = 1,
        CanResize = 2,
        CanResizeWithGrip = 3,
    }

}